﻿using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Http;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using Zhp.Common.Helper;

namespace Zhp.Common.WebApp
{
    public class CurrentUser : ICurrentUser
    {
        private readonly HttpContext _httpContext;

        public CurrentUser(IHttpContextAccessor httpContextAccessor)
        {
            _httpContext = httpContextAccessor.HttpContext;
            var tokenType = FindClaim(AuthClaimTypeConst.TokenType);
            if (tokenType != null)
            {
                TokenType = tokenType.Value;
            }
            var onlineId = FindClaim(AuthClaimTypeConst.OnlineId);
            if (onlineId != null)
            {
                OnlineId = Convert.ToInt64(onlineId.Value);
            }
            CacheId = $"{OnlineId}_{TokenType}";
            var refreshTokenId = FindClaim(AuthClaimTypeConst.RefreshToken);
            if (refreshTokenId != null)
            {
                RefreshTokenId = Convert.ToInt64(refreshTokenId.Value);
            }
            var accessTokenId = FindClaim(AuthClaimTypeConst.AccessTokenId);
            if (accessTokenId != null)
            {
                AccessTokenId = Convert.ToInt64(accessTokenId.Value);
            }
            var companyCode = FindClaim(AuthClaimTypeConst.CompanyCode);
            if (companyCode != null)
            {
                CompanyCode = Convert.ToInt32(companyCode.Value);
            }
            var userid = FindClaim(AuthClaimTypeConst.UserId);
            if (userid != null)
            {
                UserId = Convert.ToInt64(userid.Value);
            }
            var workDayId = FindClaim(AuthClaimTypeConst.WorkDayId);
            if (workDayId != null)
            {
                WorkDayId = workDayId.Value;
            }
            var userCode = FindClaim(AuthClaimTypeConst.UserCode);
            if (userCode != null)
            {
                UserCode = userCode.Value;
            }
            var userName = FindClaim(AuthClaimTypeConst.UserName);
            if (userName != null)
            {
                UserName = userName.Value;
            }
            var roleIds = FindClaim(AuthClaimTypeConst.RoleIds);
            if (roleIds != null)
            {
                RoleIds = roleIds.Value.ToObject<List<long>>();
            }
        }

        public Claim FindClaim(string claimType)
        {
            return _httpContext.User.FindFirst(claimType);
        }

        public string CacheId { get; set; }
        public long OnlineId { get; set; } = 0L;

        /// <summary>
        /// jwt编号
        /// </summary>
        public long RefreshTokenId { get; set; } = 0L;

        public long AccessTokenId { get; set; } = 0L;

        public string TokenType { get; set; }

        /// <summary>
        /// 语言编码
        /// </summary>
        public int CompanyCode { get; set; }

        /// <summary>
        /// 当前登录用户UserID
        /// </summary>
        public long UserId { get; set; } = 0L;

        /// <summary>
        /// 当前登录账号
        /// </summary>
        public string WorkDayId { get; set; }

        /// <summary>
        /// 当前登录账号
        /// </summary>
        public string UserCode { get; set; }

        /// <summary>
        /// 当前登录用户
        /// </summary>
        public string UserName { get; set; }

        /// <summary>
        /// 当前登录用户所有角色ID
        /// </summary>
        public List<long> RoleIds { get; set; } = new List<long>();

        /// <summary>
        /// 远程请求IP
        /// </summary>
        public string RemoteIpAddress => _httpContext.Connection.RemoteIpAddress.ToString();


        /// <summary>
        /// 请求携带的Token
        /// </summary>
        /// <returns></returns>
        public string GetToken()
        {
            return _httpContext.Request.Headers[AuthHeaderTypeConst.Authorization].ToString().Replace(JwtBearerDefaults.AuthenticationScheme + " ", "");
        }

        /// <summary>
        /// 是否已认证
        /// </summary>
        /// <returns></returns>
        public bool IsAuthenticated()
        {
            return _httpContext.User.Identity is { IsAuthenticated: true };
        }

        /// <summary>
        /// 获取用户身份权限
        /// </summary>
        /// <returns></returns>
        public IEnumerable<Claim> GetClaimsIdentity()
        {
            return _httpContext.User.Claims;
        }

        /// <summary>
        /// 根据权限类型获取详细权限
        /// </summary>
        /// <param name="claimType"></param>
        /// <returns></returns>
        public List<string> GetClaimValueByType(string claimType)
        {
            return (from item in GetClaimsIdentity()
                    where item.Type == claimType
                    select item.Value).ToList();
        }

        public List<string> GetUserInfoFromToken(string claimType)
        {
            var jwtHandler = new JwtSecurityTokenHandler();
            if (!string.IsNullOrEmpty(GetToken()))
            {
                JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(GetToken());

                return (from item in jwtToken.Claims
                        where item.Type == claimType
                        select item.Value).ToList();
            }

            return new List<string>();
        }
    }
}
